package project.platform.mms;

import java.io.IOException;

import javax.microedition.io.Connector;
import javax.microedition.io.PushRegistry;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextBox;
import javax.wireless.messaging.Message;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.MessageListener;
import javax.wireless.messaging.MessagePart;
import javax.wireless.messaging.MultipartMessage;

/**
 * Thread for the receipt of MMS messages. 
 * 
 * @author Paul Magrath - 05379725
 */
public class ReceiverThread implements MessageListener, Runnable {
	   	
	    /** instance of a thread for asynchronous networking and user interface. */
	    private Thread thread;
	   	
	    /** Flag to signal end of processing. */
	    private boolean done;

	    /** MMS message connection for inbound text messages. */
	    private MessageConnection mmsconn;
	    
	    /** The screen to display when we return from being paused */
	    private Displayable resumeScreen;

	    /** Text Box to display messages on screen */
		private TextBox textBox;

	    /** The applicationID on which we listen for MMS messages */
	    private String appID;

	    /** Current message read from the network. */
	    private Message msg;
	    
	    /** Address of the message's sender */
	    private String senderAddress;
	    
	    /** The subject of the message received */
	    private String subject;

	    /** The current display object. */
		private Display display;
		
		/** The screen used to display the incoming MMS */
		private Form mmsReceiveScreen;
		
		/** The contents of the MMS message received */
		private static String xml;
		
		/** 
		 * Get method for the body of the MMS message received 
		 * 
		 * @return The body of the MMS received.
		 */
		public synchronized static String getXML(){
			return ReceiverThread.xml;
		}
		
		/** 
		 * Set method for the body of the MMS message received 
		 *
		 * @param x The body of the new MMS received.
		 */
		public synchronized static void setXML(String x){
			ReceiverThread.xml = x;
		}

		
	    /**
	     * Constructor for ReceiverThread.
	     * @param appID This application's MMS application ID
	     * @param display Display that is being used
	     * @param mmsReceiveScreen Form on which to display received messages
	     */
	    public ReceiverThread(final String appID, Display display, Form mmsReceiveScreen) {
	    	ReceiverThread.setXML("");
	    	this.display = display;
	    	this.appID = appID;
	    	this.mmsReceiveScreen = mmsReceiveScreen;
	    	
	    	/** MMS connection to be read. */
	        final String mmsConnection = "mms://:" + this.appID;

	        /** Open the message connection. */
	        if (this.mmsconn == null)
				try {
	                this.mmsconn = (MessageConnection)Connector.open(mmsConnection);
	                this.mmsconn.setMessageListener(this);
	            } catch (final IOException ioe) {
	                ioe.printStackTrace();
	            }

	        /** Initialize the text if we were started manually. */
	        final String[] connections = PushRegistry.listConnections(true);

	        if ((connections == null) || (connections.length == 0)) {
	            final String s =
	            	"Waiting for MMS on applicationID " + appID + "...";
	            this.textBox = new TextBox("2BA7 Group 5 - Comms Platform", s, s.length(), 0);
	            this.resumeScreen = this.textBox;
	        }
	        this.display.setCurrent(resumeScreen);
	        this.done = false;
	        this.thread = new Thread(this);
	        this.thread.start();
	    }

	    /** Message reading thread. */
	    public void run() {
	        /** Check for mms connection. */
	        try {
	            this.msg = this.mmsconn.receive();

	            if (this.msg != null) {
	                this.senderAddress = this.msg.getAddress();

	                String titleStr = this.senderAddress.substring(6);
	                final int colonPos = titleStr.indexOf(":");

	                if (colonPos != -1)
						titleStr = titleStr.substring(0, colonPos);
	                mmsReceiveScreen.deleteAll();
	                mmsReceiveScreen.setTitle("From: " + titleStr);

	                if (this.msg instanceof MultipartMessage) {
	                    final MultipartMessage mpm = (MultipartMessage)this.msg;
	                    StringBuffer buff = new StringBuffer("Subject: ");
	                    this.subject = mpm.getSubject();
	                    buff.append(this.subject);
	                    buff.append("\nDate: ");
	                    buff.append(mpm.getTimestamp().toString());
	                    buff.append("\nContent:");

	                    final StringItem messageItem = new StringItem("Message", buff.toString());
	                    messageItem.setLayout(Item.LAYOUT_NEWLINE_AFTER);
	                    mmsReceiveScreen.append(messageItem);

	                    final MessagePart[] parts = mpm.getMessageParts();

	                    if (parts != null)
							for (int i = 0; i < parts.length; i++) {
	                            buff = new StringBuffer();

	                            final MessagePart mp = parts[i];
	                            buff.append("Content-Type: ");

	                            final String mimeType = mp.getMIMEType();
	                            buff.append(mimeType);

	                            final String contentLocation = mp.getContentLocation();
	                            buff.append("\nContent:\n");

	                            final byte[] ba = mp.getContent();

	                            try {
	                                final Image image = Image.createImage(ba, 0, ba.length);
	                                mmsReceiveScreen.append(buff.toString());

	                                final ImageItem imageItem =
	                                    new ImageItem(contentLocation, image,
	                                        Item.LAYOUT_NEWLINE_AFTER, contentLocation);
	                                mmsReceiveScreen.append(imageItem);
	                            } catch (final IllegalArgumentException iae) {
	                                buff.append(new String(ba));
	                                ReceiverThread.setXML(ReceiverThread.getXML() + new String(ba));
	                                final StringItem stringItem = new StringItem("Part", buff.toString());
	                                stringItem.setLayout(Item.LAYOUT_NEWLINE_AFTER);
	                                mmsReceiveScreen.append(stringItem);
	                            }
	                        }
	                }

	                this.display.setCurrent(mmsReceiveScreen);
	            }
	        } catch (final IOException e) {
	            e.printStackTrace();
	        }
	    }
	    
	    /**
	     * Notification that a message arrived.
	     * @param conn the connection with messages available
	     */
	    public void notifyIncomingMessage(final MessageConnection conn) {
	        if ((this.thread == null) && !this.done) {
	            this.thread = new Thread(this);
	            this.thread.start();
	        }
	    }
	}
